<template>
    <div class="goods-sku" v-if="specs">
        <dl v-for="(item, key) in list" :key="key">
            <dt>{{ item.name }}</dt>
            <dd>
                <span v-for="(it, k) in item.values" :key="it.name">
                    <span class="span" v-if="it.picture == null"
                        :class="{ selected: it.selected, disabled: it.disabled }" @click="select(key, k)">{{ it.name
                        }}</span>
                    <img :src="it.picture" v-if="it.picture" :class="{ selected: it.selected, disabled: it.disabled }"
                        @click="select(key, k)" />
                </span>
            </dd>
        </dl>
        <ButtonView :infoobj="infoobj" :skuobj="skuobj"></ButtonView>
    </div>
</template>


<script>
import { bwPowerSet } from '@/Api/constUp'
import ButtonView from './ButtonView.vue'
export default {
    props: ['specs', 'skus','infoobj','skuobj'],
    components: { ButtonView },
    data() {
        return {
            list: [],
            yes: true,//控制watch中函数只执行一次
        }
    },
    mounted() {

    },
    methods: {
        //实现规格的单一选中
        //思路：如果选中就给当前行的当前值加一个属性selected  为true
        select(key, k) {
            // console.log(this.skus);
            // console.log(this.specs);
            //this.list[key].values[k].selected=true
            if(this.list[key].values[k].selected){
                this.list[key].values[k].selected=!this.list[key].values[k].selected
                return false
            }
            //先将每一个大行变为false
            this.list[key].values.forEach((item, index) => {
                this.$set(this.list[key].values[index], "selected", false);
            })
            //让当前的变为true
            this.$set(this.list[key].values[k], "selected", true);
            //检查剩下的路径
            this.checkMap()
            var arr = this.getSelectArr().filter(it => it)
            const mapdata = this.getDataMap()
            if (arr.length == this.list.length) {
                //组合父组件要使用的数据
                var obj = {}
                //将路径拼成字符串
                var path = arr.join("*")
                //根据路径从字典中拿到id
                var skuId = mapdata[path][0]
                //根据id找到想要的数据
                var skuobj = this.skus.find(item => item.id == skuId)
                // console.log(skuobj);
                obj.skuId = skuobj.id
                obj.inventory = skuobj.inventory
                obj.price = skuobj.price
                obj.oldPrice = skuobj.oldPrice
                var str = ""
                skuobj.specs.forEach(item => {
                    str += item.name + ":" + item.valueName + ""
                })
                obj.skuname = str
                this.$emit("send", obj)
            }

        },
        //得到不同的有效组合
        getDataMap() {
            let objmap = {}
            this.skus.forEach(item => {
                //1首先是得有库存
                if (item.inventory > 0) {
                    //得到有效的属性组合
                    const arr = item.specs.map(it => it.valueName)
                    //得到所有子集
                    const allArr = bwPowerSet(arr)
                    //如果子集中是数组 我们可以约定用*连接一下，目的就是让多个数组的元素变成字符串好判断
                    //定义一个对象 
                    allArr.forEach(it => {
                        var newname = it.join("*")
                        if (objmap[newname]) {
                            //在数组中存在
                            objmap[newname].push(item.id)
                        } else {
                            //不存在
                            objmap[newname] = [item.id]
                        }
                    })
                }
            })
            return objmap
        },
        //检查路径是否有禁用的按钮  点击的时候会被调用
        checkMap() {
            //拿到有效路径
            var objmap = this.getDataMap()
            //遍历所有的specs 然后已经选择就忽略  没有选择的拿到当前的undefined的位置进行比对看看是否为有效的路径
            this.list.forEach((item, key) => {
                //需要拿到已经选中元素的数组 
                var selectArr = this.getSelectArr()
                item.values.forEach(it => {
                    //怎么知道it
                    if (selectArr.includes(it.name)) return false
                    //如果不存在让后面遍历的数据替换undefined
                    selectArr[key] = it.name
                    //将数组元素连城路径
                    var path = selectArr.filter(v => v).join("*")
                    //将路径path拿到有效路径中去判断是否存在 然后再决定是否禁用
                    if (objmap[path]) {
                        it.disabled = false
                    } else {
                        it.disabled = true
                    }
                })
            })
        },
        //已经选中元素的数组  结构[] 元素的个数和specs的长度是一样的   怎么知道哪个元素被选中了呢
        getSelectArr() {
            var arr = []
            this.specs.forEach((item, key) => {
                var obj = item.values.find(it => { return it.selected })
                arr[key] = obj ? obj.name : undefined
            })
            return arr
        }
    },
    watch: {
        specs: {
            handler() {
                if (this.yes) {
                    var mapobj = this.getDataMap()
                    this.list = this.specs
                    //处理一下this.list  让每一个属性都在有效路径的对象中过一遍，同时添加disabled属性，在有效字典的添加true 否则添加false即可
                    this.list.forEach(item => {
                        item.values.forEach(it => {
                            //能在数据字典中找到名字的 不禁用  false
                            if (mapobj[it.name]) {
                                it.disabled = false
                            } else {
                                //找不到的就禁用
                                it.disabled = true
                            }
                        })
                    })
                    this.yes = false
                }
            },
            deep: true
        }
    }
}
</script>

<style lang="scss" scoped>
@import '@/assets/css/variables.scss';

@mixin sku-state-mixin {
    border: 1px solid #e4e4e4;
    margin-right: 10px;
    cursor: pointer;

    &.selected {
        border-color: $xtxColor;
    }

    &.disabled {
        opacity: 0.6;
        border-style: dashed;
        cursor: not-allowed;
    }
}

.goods-sku {
    padding-left: 10px;
    padding-top: 20px;

    dl {
        display: flex;
        padding-bottom: 20px;
        align-items: center;

        dt {
            width: 50px;
            color: #999;
        }

        dd {
            flex: 1;
            color: #666;

            img {
                width: 50px;
                height: 50px;
                @include sku-state-mixin;
            }

            .span {
                display: inline-block;
                height: 30px;
                line-height: 28px;
                padding: 0 20px;
                @include sku-state-mixin;
            }
        }
    }
}




</style>